package counter.com.common;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import counter.com.baomidou.entity.Userinfo;
import counter.com.baomidou.service.IUserinfoService;
import counter.com.configuration.TokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;

@Order(1)
@WebFilter(filterName = "piceaFilter", urlPatterns = "/*", initParams = {
        @WebInitParam(name = "URL", value = "http://localhost:8090")})
public class CorsFilter implements Filter {
    @Autowired
    FileProperties fileProperties;

    private String WEBSOCKETPREFIX = "websocket";
    private String FILEDOWNLOADPREFIX;
    private String FILECALLBACKDOWNLOADPREFIX;
    private String LOGINURL;

    @Autowired
    IUserinfoService userinfoService;

    private static String token = "token";

    private String url;

    /**
     * 可以初始化Filter在web.xml里面配置的初始化参数
     * filter对象只会创建一次，init方法也只会执行一次。
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
//        this.url = filterConfig.getInitParameter("URL");
        LOGINURL = fileProperties.getLoginUrl();
        FILEDOWNLOADPREFIX = fileProperties.getDownloadUrlPrefix();
        WEBSOCKETPREFIX = fileProperties.getWebsocketPrefix();
        FILECALLBACKDOWNLOADPREFIX = fileProperties.getDownloadCallbackUrlPrefix();
        System.out.println("文件下载前缀:" + FILEDOWNLOADPREFIX);
        System.out.println("回执文件下载前缀:" + FILECALLBACKDOWNLOADPREFIX);
        System.out.println("WebSocket前缀:" + WEBSOCKETPREFIX);
        System.out.println("登陆URL:" + LOGINURL);
    }

    /**
     * 主要的业务代码编写方法
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //解决跨域的问题
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With,X-App-Id, X-Token,counterattack");
        response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");

//        String url = onlyTwoSplitUrl(getUrl(request.getRequestURL().toString()));
        String url = ((HttpServletRequest) servletRequest).getRequestURI();

        if (passUrl(url)) {
            filterChain.doFilter(request, response);
        } else {
            String token = request.getHeader("counterattack");
            TokenManager tokenManager = TokenManager.getInstance();
            //取得用户名称
            String username = tokenManager.getUsernameByToken(token);
            if (username != null) {
                LambdaQueryWrapper<Userinfo> wrapper = new LambdaQueryWrapper();
                wrapper.eq(Userinfo::getUsername, username);
                Userinfo user = userinfoService.getOne(wrapper);
                if (user == null) {
                    tokenManager.removeToken(token);
                    System.out.println("错误的Token信息");
                } else {
                    filterChain.doFilter(request, response);
                }
            } else {
                System.out.println("尚未取得合适的token");
            }
        }
    }

    /**
     * 临时解决下载不方便带上token而使用的一个方法
     * 将所得的url进行一次处理
     * /file/download/火行.jpg
     * ->
     * /file/download
     */
    private String onlyTwoSplitUrl(String url) {
        String[] split = url.split("/");
        if (split.length <= 3) {
            return url;
        } else {
            return "/" + split[1] + "/" + split[2];
        }
    }

    private boolean passUrl(String url) {
        if (loginUrlCheck(url) || websocketUrlCheck(url) || fileUrlCheck(url)) {
            return true;
        } else {
            return false;
        }
    }

    private boolean loginUrlCheck(String url) {
        int index = url.indexOf(LOGINURL);
        if (index != -1) {
            return true;
        }
        return false;
    }

    private boolean fileUrlCheck(String url) {
        int i = url.indexOf(FILEDOWNLOADPREFIX);
        if (i != -1) {
            //下载普通文件Url
            return true;
        }
        i = url.indexOf(FILECALLBACKDOWNLOADPREFIX);
        if (i != -1) {
            //下载回执文件url
            return true;
        }
        return false;
    }

    public static void main(String[] args) {

    }

    private boolean websocketUrlCheck(String url) {
        if (url.contains(WEBSOCKETPREFIX)) {
            return true;
        }
        return false;
    }

    /**
     * 在销毁Filter时自动调用。
     */
    @Override
    public void destroy() {
        System.out.println("我是过滤器的被销毁时调用的方法！，活不下去了................");
    }


    /**
     * http://localhost:8090/serverinfo/search
     * ->
     * /serverinfo/search
     * 取得ip地址和端口号后面的Url
     */
    private static String getUrl(String fullUrl) {
        String[] split = fullUrl.split(":");
        String lastStr = "";
        for (String a :
                split) {
            lastStr = a;
        }
        split = lastStr.split("/");
        String url = "/";
        for (int i = 1; i < split.length; i++) {
            url += split[i];
            if (i != split.length - 1) {
                url += "/";
            }
        }
        return url;
    }
}